﻿using Microsoft.Xrm.Client;
using Microsoft.Xrm.Client.Metadata;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using System;
using System.Collections.Generic;
using System.Data.Services.Common;
using System.Runtime.Serialization;

namespace Sustainalytics.DynamicsCRMGateway.Entities
{
    [DataContractAttribute(IsReference = true)]
    [EntityLogicalNameAttribute("new_claim")]
    [DataServiceKeyAttribute("Id")]
    [EntityAttribute("new_claimSet")]
    public class Claim : CrmEntity, INameable
    {
        public Claim() :
            base(EntityLogicalName)
        {
        }

        public const string EntityLogicalName = "new_claim";

        public const int EntityTypeCode = 10021;

        [AttributeLogicalNameAttribute("new_claimid")]
        public Nullable<Guid> ClaimId
        {
            get { return this.GetAttributeValue<Nullable<Guid>>("new_claimid"); }
            set { this.SetPrimaryIdAttributeValue<Nullable<Guid>>("new_claimId", "new_claimid", value); }
        }

        [AttributeLogicalNameAttribute("new_claimid")]
        public override Guid Id
        {
            get { return base.Id; }
            set { this.ClaimId = value; }
        }

        [AttributeLogicalNameAttribute("new_description")]
        public string Description
        {
            get { return this.GetAttributeValue<string>("new_description"); }
            set { this.SetAttributeValue<string>("new_description", "new_description", value); }
        }

        [AttributeLogicalNameAttribute("new_ispackage")]
        public Nullable<bool> IsPackage
        {
            get { return this.GetAttributeValue<Nullable<bool>>("new_ispackage"); }
            set { this.SetAttributeValue<Nullable<bool>>("new_ispackage", "new_ispackage", value); }
        }

        [AttributeLogicalNameAttribute("new_name")]
        public string Name
        {
            get { return this.GetAttributeValue<string>("new_name"); }
            set { this.SetAttributeValue<string>("new_name", "new_name", value); }
        }

        [AttributeLogicalNameAttribute("new_permission")]
        public string Permission
        {
            get { return this.GetAttributeValue<string>("new_permission"); }
            set { this.SetAttributeValue<string>("new_permission", "new_permission", value); }
        }

        [AttributeLogicalNameAttribute("new_value")]
        public string Value
        {
            get { return this.GetAttributeValue<string>("new_value"); }
            set { this.SetAttributeValue<string>("new_value", "new_value", value); }
        }

        [AttributeLogicalNameAttribute("new_whatisdisplayedifuserdoesnothaveclaim")]
        public string WhatIsDisplayedIfUserDoesNotHaveClaim
        {
            get { return this.GetAttributeValue<string>("new_whatisdisplayedifuserdoesnothaveclaim"); }
            set { this.SetAttributeValue<string>("new_whatisdisplayedifuserdoesnothaveclaim", "new_whatisdisplayedifuserdoesnothaveclaim", value); }
        }

        [RelationshipSchemaNameAttribute("new_new_claim_new_claim", EntityRole.Referenced)]
        public IEnumerable<Claim> Claims
        {
            get { return this.GetRelatedEntities<Claim>("new_new_claim_new_claim", EntityRole.Referenced); }
            set { this.SetRelatedEntities<Claim>("Referencednew_new_claim_new_claim", "new_new_claim_new_claim", EntityRole.Referenced, value); }
        }

        [RelationshipSchemaNameAttribute("new_new_feature_new_claim")]
        public IEnumerable<Feature> Features
        {
            get { return this.GetRelatedEntities<Feature>("new_new_feature_new_claim", null); }
            set { this.SetRelatedEntities<Feature>("new_new_feature_new_claim", "new_new_feature_new_claim", null, value); }
        }

        [AttributeLogicalNameAttribute("new_subclaimsid")]
        public CrmEntityReference SubclaimRef
        {
            get { return this.GetAttributeValue<EntityReference>("new_subclaimsid"); }
            set { this.SetAttributeValue<EntityReference>("new_SubclaimsId", "new_subclaimsid", value); }
        }

        [AttributeLogicalNameAttribute("new_subclaimsid")]
        [RelationshipSchemaNameAttribute("new_new_claim_new_claim", EntityRole.Referencing)]
        public Claim Subclaim
        {
            get { return this.GetRelatedEntity<Claim>("new_new_claim_new_claim", EntityRole.Referencing); }
            set { this.SetRelatedEntity<Claim>("Referencingnew_new_claim_new_claim", "new_new_claim_new_claim", EntityRole.Referencing, value); }
        }

        /// <summary>
        /// Constructor for populating via LINQ queries given a LINQ anonymous type
        /// <param name="anonymousType">LINQ anonymous type.</param>
        /// </summary>
        public Claim(object anonymousType) :
            this()
        {
            foreach (var p in anonymousType.GetType().GetProperties())
            {
                var value = p.GetValue(anonymousType, null);
                if (p.PropertyType == typeof(Guid))
                {
                    // Type is Guid, must be Id
                    base.Id = (Guid)value;
                    Attributes["new_claimid"] = base.Id;
                }
                else if (p.Name == "FormattedValues")
                {
                    // Add Support for FormattedValues
                    FormattedValues.AddRange((FormattedValueCollection)value);
                }
                else
                {
                    Attributes[p.Name.ToLowerInvariant()] = value;
                }
            }
        }
    }
}
